import type { UseDataModel } from './types'

/**
 * 数据声明hook
 * @param func - 返回初始数据的函数
 * @returns [数据模型, 数据更新函数]
 */
const useData: UseDataModel = function (func) {
  const model = func()
  return [
    model,
    /**
     * 合并数据，数据初始化的合并
     * @param coverData - 需要合并的数据
     * @param isReset - 是否重置性合并
     * @returns 合并后的数据
     */
    (coverData, isReset) => {
      // 待合并的数据
      const cover = (isReset || !coverData) ? useData.mergeData(func(), coverData) : coverData
      // 合并到数据模型上
      return useData.mergeData(model, cover)
    }
  ]
}

/**
 * 获取数据类型
 * @param data - 需要检测的数据
 * @returns 数据类型字符串 ('null' | 'undefined' | 'object' | 'array' | 'number' | 'string' | 'set')
 */
useData.getDataType = function (data) {
  return Object.prototype.toString.call(data).slice(8, -1).toLowerCase()
}

/**
 * 合并数据，只有类型相同的数据才会被合并
 * @param data - 原始数据
 * @param cover - 需要合并的数据
 * @returns 合并后的数据
 */
useData.mergeData = function (data, cover) {
  if (data && useData.getDataType(data) === 'object' && ['object', 'undefined'].includes(useData.getDataType(cover))) {
    cover && Object.keys(data).forEach((k) => {
      if (k in cover) {
        (data as any)[k] = cover[k]
      }
    })
  }
  return data
}

export default useData